package com.kjlink.internal.report4vue.task;

import cn.xuqiudong.common.base.vo.BooleanWithMsg;
import cn.xuqiudong.quartz.annotation.TaskJobFlag;
import cn.xuqiudong.quartz.enums.TaskJobResult;
import cn.xuqiudong.quartz.job.AbstractTaskJob;
import cn.xuqiudong.quartz.model.TaskJobLog;
import cn.xuqiudong.quartz.service.TaskJobLogDetailService;
import com.kjlink.internal.workreport.config.CommonProperties;
import com.kjlink.internal.workreport.helper.SessionHelper;
import com.kjlink.internal.workreport.jira.model.Jira;
import com.kjlink.internal.workreport.jira.service.JiraService;
import com.kjlink.internal.workreport.jira.service.JiraSynchronousService;
import com.kjlink.internal.workreport.jira.vo.JiraSynchronousResult;
import com.kjlink.internal.workreport.user.model.User;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述:
 * jira 同步定时任务
 *
 * @author Vic.xu
 * @since 2025-01-20 19:05
 */
@Component
public class jiraSynchronousTask extends AbstractTaskJob {

    @Resource
    private JiraSynchronousService jiraSynchronousService;

    @Resource
    private JiraService jiraService;

    @Resource
    private CommonProperties commonProperties;

    @Resource
    private TaskJobLogDetailService taskJobLogDetailService;


    /**
     * 每次更新3000条jira状态
     */
    private static final int UPDATE_STATUS_SIZE = 3000;

    /**
     * 从第三方数据库同步当天jira数据到本系统
     *
     * @param taskJobLog
     * @return
     */
    @TaskJobFlag(value = "jira.fetch", text = "导入jira定时任务")
    public String fetch(TaskJobLog taskJobLog) {
        SessionHelper.storeUser2InheritableLocal(User.JOB_USER);
        try {
            logger.info("into 导入jira定时任务");
            LocalDate date = LocalDate.now();
            String result = "";
            List<Jira> gongyinJiraList = jiraSynchronousService.getGongyinJiraList(date);
            JiraSynchronousResult gongyinResult = new JiraSynchronousResult();
            synchronousJiraAndLog(gongyinJiraList, gongyinResult, taskJobLog);

            result += "工银jira导入结果:" + gongyinResult;
            List<Jira> notGongyinJiraList = jiraSynchronousService.getNotGongyinJiraList(date);
            JiraSynchronousResult notGongyinResult = new JiraSynchronousResult();
            synchronousJiraAndLog(notGongyinJiraList, notGongyinResult, taskJobLog);
            result += "非工银jira导入结果:" + notGongyinResult;
            return result;
        } finally {
            SessionHelper.cleanUserFromInheritableLocal();
        }
    }

    /**
     * 同步jira 并记录定时任务日志
     */
    private void synchronousJiraAndLog(List<Jira> list, JiraSynchronousResult result, TaskJobLog taskJobLog) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (Jira jira : list) {
            BooleanWithMsg booleanWithMsg = jiraSynchronousService.synchronousJira(jira, result);
            // 无需导入的不记录，否则记录
            if (booleanWithMsg.isSuccess()) {
                TaskJobResult jobResult = booleanWithMsg.getMessage().contains("导入失败") ? TaskJobResult.FAILURE : TaskJobResult.SUCCESS;
                taskJobLogDetailService.logDetail(taskJobLog, jobResult.name(), booleanWithMsg.getMessage());
            }
        }

    }


    /**
     * 更新jira状态定时任务
     */
    @TaskJobFlag(value = "jira.status", text = "更新jira状态定时任务")
    public String updateStatus(TaskJobLog taskJobLog) {
        SessionHelper.storeUser2InheritableLocal(User.JOB_USER);
        try {
            logger.info("into 更新jira状态定时任务");
            List<Jira> jiraList = jiraService.getNotClosedJira(UPDATE_STATUS_SIZE);
            if (jiraList.size() == 0) {
                return "本次没有未关闭的jira需要更新状态";
            }
            // list 转map 方便查找
            Map<String, Jira> jiraMap = jiraList.stream()
                    .collect(Collectors.toMap(Jira::getCode, jira -> jira, (oldValue, newValue) -> newValue));

            StringBuilder result = new StringBuilder();
            //工银jira前缀
            String jiraPrefix = commonProperties.getJiraPrefix();

            Set<String> gongyinCodes = new HashSet<>();
            Set<String> notGongyinCodes = new HashSet<>();

            // 遍历 jiraList，根据状态字段将元素分类
            for (Jira jira : jiraList) {
                if (jira.getCode().startsWith(jiraPrefix)) {
                    gongyinCodes.add(jira.getCode());
                } else {
                    notGongyinCodes.add(jira.getCode());
                }
            }
            List<Jira> gongyinJiraList = jiraSynchronousService.getGongyinJiraList(new ArrayList<String>(gongyinCodes));
            int gongyinUpdated = updateStatus(gongyinJiraList, jiraMap, taskJobLog);
            List<Jira> notGongyinJiraList = jiraSynchronousService.getNotGongyinJiraList(new ArrayList<String>(notGongyinCodes));
            int notGongyinUpdated = updateStatus(notGongyinJiraList, jiraMap, taskJobLog);
            result.append("待更新jira状态总数:").append(jiraList.size()).append("条;\n");
            result.append("更新工银jira状态:").append(gongyinUpdated).append("/").append(gongyinJiraList.size()).append("条;\n")
                    .append("更新非工银jira状态:").append(notGongyinUpdated).append("/").append(notGongyinJiraList.size()).append("条");
            return result.toString();
        } finally {
            SessionHelper.cleanUserFromInheritableLocal();
        }
    }


    /**
     * @param jiraList 从第三方查询来的最新数据
     * @param jiraMap  本系统的jira数据
     */
    private int updateStatus(List<Jira> jiraList, Map<String, Jira> jiraMap, TaskJobLog taskJobLog) {
        int changedCount = 0;
        for (Jira jira : jiraList) {
            Jira localJira = jiraMap.get(jira.getCode());
            if (localJira == null) {
                continue;
            }
            BooleanWithMsg hasChanged = jiraSynchronousService.updateJiraOtherFieldFromDb(localJira, jira);
            if (hasChanged.isSuccess()) {
                changedCount++;
                String msg = "[" + jira.getCode() + "] " + hasChanged.getMessage();
                taskJobLogDetailService.logDetail(taskJobLog, TaskJobResult.SUCCESS.name(), msg);
            }
        }
        return changedCount;
    }

}
